#include "userMain.h"
#include "userC_IIC.h"
/**********************************************?????***************************************************/

//#define Cx_ASK_Test_Error     

#ifdef  Cx_ASK_Test_Error
#define Cx_ASK_Test_Error
unsigned int Cx_Right_Count = 0;
unsigned int Cx_Error_Count = 0;

#endif

/*IIC time sequence*/
#define     Cx_THD_STA     4            // time of SCL&SDA keep start level 
#define     Cx_TSU_STA     4            //time of SDA start condition
#define     Cx_TYLOW       2            // time of SCL output low level (half of TLOW)
#define     Cx_THIGH       4            //time of SDA output high level
#define     Cx_THHIGN      2            //time of SDA output high level: half
#define     Cx_TSU_STO     4            //time of establish SDA stop condition
#define     Cx_TBUF        8            //time of bus release

#define     Delay_us_2		_NOP;_NOP;_NOP;_NOP;_NOP;;_NOP;_NOP;_NOP
#define     Delay_us_4		Delay_us_2;Delay_us_2
#define     Delay_us_8		Delay_us_4;Delay_us_4

#define     Dely_us_Cx_THD_STA			Delay_us_4
#define     Dely_us_Cx_TSU_STA			Delay_us_4
#define     Dely_us_Cx_TYLOW			Delay_us_2
#define     Dely_us_Cx_THIGH			Delay_us_4
#define     Dely_us_Cx_THHIGN			Delay_us_2
#define     Dely_us_Cx_TSU_STO			Delay_us_4
#define     Dely_us_Cx_TBUF				Delay_us_8

/***********************************************************************************************************/
/*SDA and SCL IO configure*/
#define     Cx_I2C_SDA_PORT     GPIOB
#define	    Cx_I2C_SDA_PIN		GPIO_Pin_7
#define     Cx_I2C_SCL_PORT     GPIOB
#define	    Cx_I2C_SCL_PIN		GPIO_Pin_6
#define     Cx_SDA_1       	    GPIO_SetBits(Cx_I2C_SDA_PORT,Cx_I2C_SDA_PIN)
#define     Cx_SDA_0       	    GPIO_ResetBits(Cx_I2C_SDA_PORT,Cx_I2C_SDA_PIN)
#define     Cx_SCL_1            GPIO_SetBits(Cx_I2C_SCL_PORT,Cx_I2C_SCL_PIN)
#define     Cx_SCL_0            GPIO_ResetBits(Cx_I2C_SCL_PORT,Cx_I2C_SCL_PIN)
#define     Cx_SDA_IN           GPIO_ReadInputDataBit(Cx_I2C_SDA_PORT,Cx_I2C_SDA_PIN)
/***********************************************************************************************************/
void Cx_OUT_SDA_config(void);
void Cx_IN_SDA_config(void);
void Cx_OUT_SCL_config(void);
void Cx_IN_SCL_config(void);

void Cx_OUT_SDA_config(void)
{
    GPIO_InitTypeDef        GPIO_InitStructure;

	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = Cx_I2C_SDA_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(Cx_I2C_SDA_PORT, &GPIO_InitStructure);
}

void Cx_IN_SDA_config(void)
{
    GPIO_InitTypeDef        GPIO_InitStructure;

	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = Cx_I2C_SDA_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(Cx_I2C_SDA_PORT, &GPIO_InitStructure);
}

void Cx_OUT_SCL_config(void)
{
    GPIO_InitTypeDef        GPIO_InitStructure;

	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = Cx_I2C_SCL_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(Cx_I2C_SCL_PORT, &GPIO_InitStructure);
}

void Cx_IN_SCL_config(void)
{
    GPIO_InitTypeDef        GPIO_InitStructure;

	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = Cx_I2C_SCL_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(Cx_I2C_SCL_PORT, &GPIO_InitStructure);
}



/*IIC initial function*/ 
void Cx_IIC_Initial(void)
{
    Cx_OUT_SCL_config(); 
    Cx_OUT_SDA_config();
    Cx_SDA_1;
    Cx_SCL_1;    
}

/*IIC start function */
void Cx_IIC_Start(void)
{
    Cx_OUT_SDA_config();
    Cx_SCL_1;
    Cx_SDA_1;
  	Dely_us_Cx_TSU_STA;
    Cx_SDA_0;
    Dely_us_Cx_THD_STA;
    Cx_SCL_0;
    Cx_SDA_0;
    Dely_us_Cx_TYLOW;  
  }

/*IIC stop function*/
void Cx_IIC_Stop(void)
{
    Cx_OUT_SDA_config();
    Cx_SCL_0;
    Cx_SDA_0;  
    Dely_us_Cx_TYLOW;  
    Cx_SCL_1;
    Dely_us_Cx_TSU_STO;
    Cx_SDA_1;
    Dely_us_Cx_TBUF;
  }

/*IIC Master ack function*/
/**************************************************/
void Cx_Ack(void)
{
    Cx_OUT_SDA_config();
    Cx_SCL_0;
    Cx_SDA_0;
    Dely_us_Cx_TYLOW;
    Cx_SCL_1;
    Dely_us_Cx_THIGH;
    Cx_SCL_0;
    Dely_us_Cx_TYLOW;
}
/*IIC Master no ack function*/
/*************************************************/
void Cx_NoAck(void)  
{
    Cx_OUT_SDA_config();
    Cx_SCL_0;
    Cx_SDA_1;
    Dely_us_Cx_TYLOW;
    Cx_SCL_1;
    Dely_us_Cx_THIGH;
    Cx_SCL_0;
    Dely_us_Cx_TYLOW;
}
/*IIC Master ack Test function*/
unsigned char Cx_TestAck(void)     
{ 
    int Cx_IIC_ACK_TEST;
    Cx_IN_SDA_config();
    Cx_SCL_0;
    Dely_us_Cx_TYLOW;
    Cx_SCL_1;
    Dely_us_Cx_THIGH;
  
    if(Cx_SDA_IN==0x00)
    {
        Cx_IIC_ACK_TEST=0;
        #ifdef Cx_ASK_Test_Error
        #define Cx_ASK_Test_Error
        Cx_Right_Count++;
        #endif
    }
    else
    {
        Cx_IIC_ACK_TEST=1;
        #ifdef Cx_ASK_Test_Error
        #define Cx_ASK_Test_Error
        Cx_Error_Count++;
        #endif
    }
  
    Cx_SCL_0;
    return Cx_IIC_ACK_TEST;
}
/*write one byte(8 bits)*/
void Cx_Write8Bit(unsigned char Cx_input)
{
    int Cx_temp;
    Cx_OUT_SDA_config();
    for(Cx_temp=8;Cx_temp>0;Cx_temp--)
    {   
        Cx_SCL_0;
        if((Cx_input&0x80)==0)
            Cx_SDA_0;
        else
            Cx_SDA_1;
        Dely_us_Cx_TYLOW;
        Cx_SCL_1; 
        Dely_us_Cx_THIGH;
        Cx_SCL_0;
        Dely_us_Cx_TYLOW;
        Cx_input=Cx_input<<1;
    }
}
/*read one byte (8 bits)*/
/****************************************************/
unsigned char Cx_Read8Bit(void)    
{
    int Cx_temp;
    unsigned char Cx_rbyte=0x00;
    Cx_IN_SDA_config();
    for(Cx_temp=8;Cx_temp>0;Cx_temp--)
    {
        Cx_SCL_0;
        Dely_us_Cx_TYLOW;
        Cx_SCL_1;
        Dely_us_Cx_THHIGN;
        Cx_rbyte=Cx_rbyte<<1;
        if(Cx_SDA_IN==0x00)
            Cx_rbyte=Cx_rbyte|0x00;
        else
            Cx_rbyte=Cx_rbyte|0x01;
        Dely_us_Cx_THHIGN;    
        Cx_SCL_0;
        Dely_us_Cx_TYLOW;
    }
    return(Cx_rbyte);
}
/***********IIC IO Release*********************/
void Cx_IIC_End(void)
{
    Dely_us_Cx_TBUF;
    Cx_IN_SCL_config();
    Cx_IN_SDA_config();
    Dely_us_Cx_TBUF;
}

